package edu.chds.ui
{
	import com.allthingsmotion.utils.MathXML;
	
	import edu.chds.data.xml.TimelineReader;
	import edu.chds.utils.TimelineLoader;
	
	import fl.controls.Button;
	import fl.controls.ComboBox;
	import fl.controls.TextArea;
	import fl.motion.Color;
	
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	
	import gs.*;
	import gs.easing.*;

	public class Timeline extends MovieClip
	{
		public static const COMPLETE_NODES:String = "completeNodes";
		public static const COMPLETE_LINE:String = "completeLine";
		public static const NODE_CLICKED:String = "nodeClicked";
		private var _yearBuffer:uint = 15; //amount of years that the timeline extends left or right from _minYear && _maxYear		
		private var _xScaleNode:Number = 1.2;
		private var _yScaleNode:Number = 6;
		private var _tintStatutes:uint = 0xffff99;
		private var _tintHspds:uint = 0x990000;
		private var _tintStrategies:uint = 0x336600;
		private var _tintMultiplier:Number = .5;
		
		public var xmlPath:String;
		public var cbType:ComboBox;
		public var cbYear:ComboBox;
		public var taKeywords:TextArea;
		public var btSearch:Button;
		public var btSearchKey:Button;
		public var taList:TextArea;
		public var timelineLoader:TimelineLoader;
		
		public var reader:TimelineReader;
		public var lines:Array = new Array();
		public var linesContainer:MovieClip = new MovieClip();
		public var nodes:Array = new Array;		
		public var nodesContainer:MovieClip = new MovieClip();
		private var _monthFormat:TextFormat = new TextFormat();
		private var _tfMonth:TextField;
		private var _minYear:uint;
		private var _maxYear:uint;
		private var _minYearBuffer:uint;
		private var _maxYearBuffer:uint;
		private var _nodesAverage:Number;
		
				
		public function Timeline()
		{
			/* xmlPath = path;
			cbType = cb;
			cbYear = cbY;
			taKeywords = taK;
			btSearch = btS;
			btSearchKey = btK;
			taList = ta;
			
			timelineLoader = new TimelineLoader(path, this);
			*/
			this.addChild(linesContainer);
			this.addChild(nodesContainer);							
			init();
		}
		private function init():void {
			linesContainer.x = nodesContainer.x = 0;
			linesContainer.y = nodesContainer.y = 0;
			//Call the function to format Text in Timeline (not included are the DisplayObjects nested in the Timeline Children)
			formatText();
		}
		public function generateTimeline(tReader:TimelineReader):void {
			trace("Generate Timeline");
			reader = tReader;
			var yearX:Number = 100;
			var yearY:int = stage.stageHeight;
			
			for (var i:int = _minYearBuffer; i <= _maxYearBuffer; i++){
				var timelineYear:TimelineYear = new TimelineYear();
				linesContainer.addChild(timelineYear);
				lines.push(timelineYear);
				
				//else if statements to size the years in the timeline according to printed version
				//NEED TO BE MORE DYNAMIC BY USING AN ALGORITHM THAT LOOKS AT XML DATA
				if (i < 2001) {
					//trace ("Normal size");
				} else if (i >= 2001 && i < 2004) {
					timelineYear.bg.width *= 10;
					generateMonths(timelineYear);
				} else if (i >= 2004 && i <= _maxYear) {
					timelineYear.bg.width *= 15;
					generateMonths(timelineYear);
				} else if (i > _maxYear) {
					
				} else {
					trace ("ERROR in reading data");
				}
				timelineYear.x = yearX;
				timelineYear.y = yearY - timelineYear.height*2;
				timelineYear.year.text = i.toString();	
							
				//YearX += needs to be before -= timelineYear.year.width/2
				//because the year textfield will be pushed to the left and increase width)
				yearX += timelineYear.width;
				timelineYear.year.x -= timelineYear.year.width/2;	
//				trace("timelineYear.x " + timelineYear.x);
//				trace("timelineYear.y " + timelineYear.y);
			}
			dispatchEvent(new Event(Timeline.COMPLETE_LINE));
		}
		private function generateMonths(tYear:TimelineYear):void {
			var timelineYear:TimelineYear = tYear;
			var _months:uint = 12;
			var _monthSpacing:Number = timelineYear.bg.width/_months;
			var _tfSpacing:uint = 3;
			
			timelineYear.months = new Array();
			//makes months display objects depending on amount of months user wants displayed and spaces them out by _monthSpacing
			for (var i:int=0; i<_months; i++) {
				var monthTick:TimelineTick = new TimelineTick;
				_tfMonth = new TextField();
				_tfMonth.width = 36;
				_tfMonth.height = 16;

				timelineYear.addChild(monthTick);
				timelineYear.months.push(monthTick);
				monthTick.y = timelineYear.bg.height/2 - monthTick.height/2;
				monthTick.x = _monthSpacing * i;
				
				 //switch to make months different depending on value of i
				 switch(i) {
					case 0:
						monthTick.value = "January";
						monthTick.visible = false;
					break;
					case 1:
						monthTick.value = "February";
					break;
					case 2:
						monthTick.value = "March";
						monthTick.label = "March";
						_tfMonth.text = monthTick.label;
						addMonth(timelineYear, monthTick, _tfSpacing);
					break;
					case 3:
						monthTick.value = "April";
					break;
					case 4:
						monthTick.value = "May";
						monthTick.label = "May";
						_tfMonth.text = monthTick.label;
						addMonth(timelineYear, monthTick, _tfSpacing);
					break;
					case 5:
						monthTick.value = "June";
					break;
					case 6:
						monthTick.value = "July";
						monthTick.label = "July";
						_tfMonth.text = monthTick.label;
						addMonth(timelineYear, monthTick, _tfSpacing);
					break;
					case 7:
						monthTick.value = "August";
					break;
					case 8:
						monthTick.value = "September";
						monthTick.label = "Sept";
						_tfMonth.text = monthTick.label;
						addMonth(timelineYear, monthTick, _tfSpacing);
					break;
					case 9:
						monthTick.value = "October";
					break;
					case 10:
						monthTick.value = "November";
						monthTick.label = "Nov";
						_tfMonth.text = monthTick.label;
						addMonth(timelineYear, monthTick, _tfSpacing);
					break;
					case 11:
						monthTick.value = "December";
//						monthTick.visible = false;
					break;
					default:
						monthTick.value = "January";
						
					break;
				} 
			}
		}
		public function generateNodes(tReader:TimelineReader):void {
			trace("Generate Nodes");
			var tintColor:Color = new Color();
			reader = tReader;  
			//cycle through items or documents in the XML file
			for each(var item:XML in reader.documents) {
				//trace (item);
				var timelineNode:TimelineNode = new TimelineNode();
				nodesContainer.addChild(timelineNode);
				nodes.push(timelineNode);
				//trace("timelineNOde.active " + timelineNode.active);
//				trace("item.index " + reader.documents);
				timelineNode.year = item.year;
				timelineNode.month = item.month;
//				timelineNode.xpos = _minYear;
				//trace ('timelineNode.year', timelineNode.year);
				//trace ('timelineNode.month', timelineNode.month);
											
				timelineNode.title.text = item.title;
				timelineNode.summary.text = item.summary;
				timelineNode.type.text = item.type;
				timelineNode.date.text = item.month + " " + item.year;
				timelineNode.THUMBNAIL_LINK = "https://www.hsdl.org/" + item.thumb;
				
//				timelineNode.x = timelineNode.xpos * (timelineNode.width + 5);
				timelineNode.y = Math.random() * stage.stageHeight/2 + timelineNode.height/2;//Math.random() * stage.stageHeight;
				
				//Cycle through lines array to find where years == timelineNode.year 
				//then place timelineNode.x = timelineYear.x
				for(var j:int = 0; j < lines.length - 1; j++) {
					var lineYear:uint = uint(lines[j].year.text);
					if (timelineNode.year == lineYear) {
						//Places timelineNode.x to same value of the corresponding line
						timelineNode.x = lines[j].x + timelineNode.width/2;
						
						if(lines[j].months != null) {
							trace('in months != null');
							for(var k:int = 0; k < lines[j].months.length - 1; k++) {
								//trace(lines[j].name + ' months ' + lines[j].months[k].value);
								//trace('timelineNode.month ' + timelineNode.month);
								if (timelineNode.month == lines[j].months[k].value) {
									timelineNode.x = lines[j].x + lines[j].months[k].x + timelineNode.width/2;
									trace('moved timelineNode.x ' + timelineNode.x);
								}
							}
						}
						
					} 
				}
				timelineNode.buttonMode = true;
				timelineNode.addEventListener(MouseEvent.CLICK, nodeClick);
				timelineNode.xScale = _xScaleNode;
				timelineNode.yScale = _yScaleNode;
				
				//visually change timelineNode properties depending on type of document
				switch (timelineNode.type.text) {
					
					case "Statutes":
					tintColor.setTint(_tintStatutes, _tintMultiplier);
					break;
					case "HSPDs":
					tintColor.setTint(_tintHspds, _tintMultiplier);
					break;
					case "Strategies & Plans":
					tintColor.setTint(_tintStrategies, _tintMultiplier);
					break;
					default:
					break;
				}
				timelineNode.bg.transform.colorTransform = tintColor;
			}
			//Dispatch Event for when after TimelineNodes are generated and on stage
			dispatchEvent(new Event(Timeline.COMPLETE_NODES));
		}
		/**
		 * 
		 * LEFT OFF 090415
		 * Something wrong with node.height gives incorrect value
		 * //Linked to TextArea values? wtf!!
		 * also 0 value for node.y is on 100?
		 * 
		 */		
		private function nodeClick(e:MouseEvent):void {
			dispatchEvent(new Event(Timeline.NODE_CLICKED));
			var node:TimelineNode = TimelineNode(e.currentTarget);
			var activeNode:TimelineNode;
			
			/* trace('BEFOREnode.y ' + node.y);
			trace('BEFOREnode.height ' + node.height); 
			trace('node.bg.width ', widthBefore, widthAfter, heightBefore, heightAfter);
			 */
			 //sorts through nodes array to find if nodeClicked == nodes[]	
			 //in this section the if block use node
			 //in this section the else block use nodes[i]		
			for (var i:int = 0; i < nodes.length; i++) {
			
//				trace('node ' + node.name);
//				trace('nodes[i] ' + nodes[i].name);
				
				//conditional checks if nodeClicked == nodes[i]
				//animates node to expand and display other information
				if (node.name == nodes[i].name) {// && nodes[i].active == false) {
					node.thumb.visible = node.keywords.visible = true;
					nodesContainer.setChildIndex(node, nodesContainer.numChildren - 1);
					node.removeEventListener(MouseEvent.CLICK, nodeClick);
					node.thumb.load(node.THUMBNAIL_LINK);
					//trace('node.active if ' + node.active);
//					nodes[i].active = true;
					TweenMax.to(node.date, 0.75, {x:node.xDateAfter, y:node.yDateAfter, ease:Back.easeIn});
					TweenMax.to(node.type, 0.75, {x:node.xTypeAfter, y:node.yTypeAfter, ease:Back.easeIn});
					TweenMax.to(node.title, 0.75, {x:node.xTitleAfter, y:node.yTitleAfter, width:node.wTitleAfter, height:node.hTitleAfter, ease:Back.easeIn});
					TweenMax.to(node.summary, 0.75, {x:node.xSummaryAfter, y:node.ySummaryAfter, width:node.wSummaryAfter, height:node.hSummaryAfter, alpha:1, ease:Back.easeIn});
					TweenMax.to(node.thumb, 0.75, {x:node.xThumbAfter, y:node.yThumbAfter, alpha:1, ease:Back.easeIn});
					TweenMax.to(node.keywords, 0.75, {x:node.xKeywordsAfter, y:node.yKeywordsAfter, width:node.wKeywordsAfter, height:node.hKeywordsAfter, alpha:1, ease:Back.easeIn});
					TweenMax.to(node.bg, 0.75, {width:node.widthAfter, height:node.heightAfter, ease:Back.easeIn, onComplete:checkOffStage, onCompleteParams:[node]});
				} 
				//animates node to contract back to initial settings
				 else {
//					node.active = false;
					TweenMax.to(nodes[i].type, 0.75, {x:nodes[i].xTypeBefore, y:nodes[i].yTypeBefore, ease:Back.easeIn});
					TweenMax.to(nodes[i].date, 0.75, {x:nodes[i].xDateBefore, y:nodes[i].yDateBefore, ease:Back.easeIn});
					TweenMax.to(nodes[i].title, 0.75, {x:nodes[i].xTitleBefore, y:nodes[i].yTitleBefore, width:nodes[i].wTitleBefore, height:nodes[i].hTitleBefore, ease:Back.easeIn});
					TweenMax.to(nodes[i].summary, 0.75, {x:nodes[i].xSummaryBefore, y:nodes[i].ySummaryBefore, width:nodes[i].wSummaryBefore, height:nodes[i].hSummaryBefore, alpha:0, ease:Back.easeIn});
					TweenMax.to(nodes[i].thumb, 0.75, {x:nodes[i].xThumbBefore, y:nodes[i].yThumbBefore, alpha:0, ease:Back.easeIn});
					TweenMax.to(nodes[i].keywords, 0.75, {x:nodes[i].xKeywordsBefore, y:nodes[i].yKeywordsBefore, width:nodes[i].wKeywordsBefore, height:nodes[i].hKeywordsBefore, alpha:0, ease:Back.easeIn});
					TweenMax.to(nodes[i].bg, 0.75, {width:nodes[i].widthBefore, height:nodes[i].heightBefore, ease:Back.easeIn, onComplete:function():void{
//						nodes[i].addEventListener(MouseEvent.CLICK, nodeClick);			
//						node.active = false;
					}});
					nodes[i].thumb.visible = nodes[i].keywords.visible = false;
					nodes[i].addEventListener(MouseEvent.CLICK, nodeClick);								 	 
				}  
			}
			//trace ("CLICK");
//			trace("node.keywords ", node.keywords.width);
		}
		private function checkOffStage(nodeClicked:TimelineNode):void {
			trace("checkOffStage");
			var node:TimelineNode = nodeClicked;
			var nodeLeft:Number = nodesContainer.x + (node.x - node.width/2);
			var nodeTop:Number = nodesContainer.y + (node.y - node.bg.height);
			var nodeRight:Number = nodeLeft + node.width;
			var nodeBottom:Number = nodeTop + node.bg.height;
			
			var left:uint = 0;
			var top:uint = 0;
			var right:uint = stage.stageWidth;
			var bottom:uint = stage.stageHeight;

			//trace('BEFOREnode.y ' + node.y);
			//trace('BEFOREnode.height ' + node.height);
						
			//trace('nodeTop ' + nodeTop);
			
			//checks to see if node is out of view and then pushes it down to display all of it
			if ( nodeTop < top) {
				node.y = top + node.bg.height; 
			}
			nodeTop = nodesContainer.y + (node.y - node.height);
			//trace('nodeTop ' + nodeTop);
			//trace('node.y ' + node.y);
		}
		private function formatText():void {
			_monthFormat.align = TextFormatAlign.CENTER;
			_monthFormat.size = 10;
			_monthFormat.color = 0x000000;
			_monthFormat.font = "Arial";
			
//			return _monthFormat;
		}
		//used to addMonth to Timeline for Years that call for months to be displayed
		private function addMonth(tYear:TimelineYear, mClick:TimelineTick, tfSpacing:uint) {
			var timelineYear:TimelineYear = tYear;
			var monthTick:TimelineTick = mClick;
			var _tfSpacing:uint = tfSpacing;
			timelineYear.addChild(_tfMonth);
			_tfMonth.y = monthTick.y + monthTick.height + _tfSpacing;
			_tfMonth.x = monthTick.x - _tfMonth.width/2;
			_tfMonth.setTextFormat(_monthFormat);
		}
		
		/**
		 * Get and Set methods 
		 * @return 
		 * 
		 */
		 		
		public function get minYear():uint {
			return _minYear;
		}
		public function set minYear(yearMin:uint):void {
			_minYear = yearMin;
			_minYearBuffer = _minYear - _yearBuffer;
		}
		public function get maxYear():uint {
			return _maxYear;
		}
		public function set maxYear(yearMax:uint):void {
			_maxYear = yearMax;
			_maxYearBuffer = _maxYear + _yearBuffer;
		}
		public function get nodesAverage():Number {
			return _nodesAverage;
		}
		public function set nodesAverage(yearAv:Number):void {
			_nodesAverage = yearAv;
		}
	}
}